Skip to content

Support RowsColumnScanner on Go 1.27 - #649

Merged
XSAM merged 8 commits into
mainfrom
issue-557-rows-column-scanner
Sep 6, 2026
Merged

Support RowsColumnScanner on Go 1.27#649
XSAM merged 8 commits into
mainfrom
issue-557-rows-column-scanner

Conversation

@XSAM

@XSAM XSAM commented Sep 4, 2026

Copy link
Copy Markdown
Owner

Summary

Go 1.27 applications can retain driver-owned column scanning when a driver is wrapped by otelsql. This lets drivers such as pgx decode PostgreSQL arrays, ranges, and other custom types directly instead of losing that capability at the instrumentation boundary.

The wrapper exposes driver.RowsColumnScanner only when the underlying rows implement it. NextRow continues to emit row events, and non-EOF errors from both NextRow and ScanColumn are recorded on the sql.rows span. ScanColumn errors are returned unchanged to the caller. Earlier Go versions keep the ordinary rows wrapper.

Fixes #557.

Validation

  • GitHub CI covers lint, coverage, race, CodeQL, and changelog protection checks.
  • Compatibility tests cover Go 1.27, 1.26, and 1.25 across the configured Linux, macOS, and Windows matrix.
  • Direct and database/sql integration tests verify ScanColumn error propagation, Error span status, and exception recording.
  • PostgreSQL 17 integration passes against pgx PR #2542 at ccd2e56d9941 in all five pgx query modes.
  • Wrapped pgx matches direct pgx for bigint[], int4range, and the sql.ConvertAssign boolean fallback.
  • Successful wrapped queries emit sql.rows.next without row-span errors.
  • A negative control with otelsql v0.43.0 fails to scan bigint[] into []int64, confirming that the integration test detects the missing interface.

New concepts

driver.RowsColumnScanner is an optional Go 1.27 interface that lets a SQL driver advance rows with NextRow and scan each column directly into the caller's destination. database/sql stops calling legacy Rows.Next when this interface is present, so a wrapper must preserve it conditionally rather than implement it for every driver.

This is useful when decoding depends on driver-specific context. pgx can retain its PostgreSQL type map, OID, wire format, and raw bytes instead of first reducing the value to a generic driver.Value.

Post-Deploy Monitoring & Validation

  • Search application logs for unsupported Scan, cannot scan, and sql: Scan error after adopting the release.
  • Watch the error rate and status of sql.rows spans for Go 1.27 applications.
  • Healthy signal: wrapped and unwrapped drivers return identical values, and complex pgx types scan without adapters.
  • Failure signal: new scan conversion errors, changed destination values, or elevated sql.rows error spans.
  • Mitigation: revert to the previous otelsql release or temporarily use the driver's documented scan adapter.
  • Validation window and owner: maintainers during pre-release testing and the first release cycle with Go 1.27.

@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.8%. Comparing base (f1fb0b8) to head (d105699).

Additional details and impacted files
@@           Coverage Diff           @@
##            main    #649     +/-   ##
=======================================
+ Coverage   89.5%   89.8%   +0.2%     
=======================================
  Files         15      16      +1     
  Lines        582     599     +17     
=======================================
+ Hits         521     538     +17     
  Misses        61      61             

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@XSAM XSAM added this to the v0.44.0 milestone Sep 5, 2026
@XSAM

XSAM commented Sep 5, 2026

Copy link
Copy Markdown
Owner Author

A related work in driver lib: jackc/pgx#2542

@XSAM
XSAM marked this pull request as ready for review September 5, 2026 05:57
XSAM added 3 commits September 4, 2026 23:10
Record ScanColumn errors on rows spans and cover propagation through database/sql.
@XSAM
XSAM merged commit a7f3be3 into main Sep 6, 2026
24 checks passed
@XSAM
XSAM deleted the issue-557-rows-column-scanner branch September 6, 2026 20:11
@XSAM XSAM mentioned this pull request Sep 6, 2026
XSAM added a commit that referenced this pull request Sep 6, 2026
This release is the last to support [Go 1.25].
The next release will require at least [Go 1.26].

### Added

- Support testing of [Go 1.27]. (#650)
- Add `WithSpanErrorAttributesGetter` option to set additional
attributes (e.g., `db.response.status_code`) on spans when an operation
returns an error. (#651)
- Add `SpanOptions.RowsChildOfQuery` to create `sql.rows` spans as
children of the `sql.conn.query` or `sql.stmt.query` span that produced
them, so concurrent queries can be correlated with their result
iteration. (#652)
- Support `driver.RowsColumnScanner` on [Go 1.27]. (#649)

### Changed

- Replace `ErrorTypeAttributes` with `ErrorTypeAttribute` to avoid
allocating an additional slice. (#643)
- Upgrade OTel to `v1.46.0`. (#644)

### Fixed

- `db.client.operation.duration` histogram now uses the explicit bucket
boundaries recommended by the OTel Semantic Conventions (`0.001` to `10`
seconds) instead of the SDK defaults, which placed virtually all
database operations in the first bucket. (#632)

[Go 1.26]: https://go.dev/doc/go1.26
[Go 1.25]: https://go.dev/doc/go1.25
[Go 1.27]: https://go.dev/doc/go1.27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for upcoming driver.RowsColumnScanner interface

1 participant